/*
 * Copyright 2008 Brian Watkins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package bw.os;

import java.util.*;
import java.util.zip.*;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import bw.net.*;
import bw.util.*;

public class HttpObjectWriter extends AsynchronousObjectWriter
{
    public static final String REMOTE_STORE = "/store";
    public static final String REMOTE_ERASE = "/remove";

    private String _httpRoot = null;
    //private PersistentObjectWriter _localWriter = null;

    public HttpObjectWriter ( ServletContext context )
    {
        super( context );

        _httpRoot = context.getInitParameter( "objectStore.httpWriter.root" );
        
        Log.getInstance().write( "Using HttpObjectWriter at: " + _httpRoot );
        
        //if ( "true".equalsIgnoreCase( context.getInitParameter( "objectStore.http.backupLocally" ) ) )
        //{
        //    Log.getInstance().write( "Using local disc cache for backups of http remote store data." );
        //    _localWriter = new FileObjectHandler( context );

        //}
    }

    public HttpObjectWriter ( String httpRoot )
    {
        super();

        _httpRoot = httpRoot;
        
        Log.getInstance().write( "Using HttpObjectWriter at: " + _httpRoot );
    }

    protected void asynchronousWrite ( String key, Object obj )
        throws Exception
    {
        String urlStr = _httpRoot + REMOTE_STORE + "/" + makeFilename( key );
        URL url = new URL( urlStr );
        
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput( true );
        conn.setRequestMethod( "PUT" );

        ObjectOutputStream oos = getObjectOutputStream( conn.getOutputStream() );
        oos.writeObject( obj );
        oos.close();

        //when we attempt to get the response code the request will be PUT to the server
        if ( conn.getResponseCode() != HttpURLConnection.HTTP_OK )
        {
            throw new Exception( "Problem putting response to server! " +
                                 urlStr + " ==> " + conn.getResponseCode() );
        }

        //if ( _localWriter != null && obj != null )
        //{
        //    _localWriter.write( key, obj );
        // }
    }

    protected void asynchronousErase ( String key )
        throws Exception
    {
        String filename = makeFilename( key );

        NetResource resource = new NetResource( _httpRoot + REMOTE_ERASE + "/" + filename );
        HttpURLConnection conn = resource.getURLConnection();
        
        if ( conn.getResponseCode() != HttpURLConnection.HTTP_OK )
        {
            throw new Exception( "Problem erasing key: " + key + "\n" +
                                 resource.toString() + " ==> " + conn.getResponseCode() );
        }

        //if ( _localWriter != null )
        //{
        //    _localWriter.erase( key );
        //}
    }

    public static void main ( String [] args )
    {
        try
        {
            String httpRoot = args[0];
            File dir = new File( args[1] );

            HttpObjectWriter writer = new HttpObjectWriter( httpRoot );
            
            if ( dir.isDirectory() )
            {
                File [] files = dir.listFiles();

                for ( int i = 0; i < files.length; i++ )
                {
                    String name = files[i].getName();
                    if ( name.startsWith( PersistentObjectHandler.FILE_PREFIX ) &&
                         name.endsWith( PersistentObjectHandler.FILE_EXT ) )
                    {
                        System.out.println( "Uploading: " + files[i].getName() );

                        ObjectInputStream ois = new ObjectInputStream( new GZIPInputStream( new FileInputStream( files[i] ) ) );
                        Object obj = ois.readObject();
                        ois.close();

                        String key = writer.extractKey( files[i].getName() );

                        writer.asynchronousWrite( key, obj );
                    }
                }
            }

        }
        catch ( Exception ex )
        {
            ex.printStackTrace();
        }
    }

}